package com.woniuxy.uums.service.impl;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.uums.pojo.Owner;
import com.woniuxy.uums.pojo.WcnUser;
import com.woniuxy.uums.service.BaiduFaceService;
import com.woniuxy.uums.service.OwnerService;
import com.woniuxy.uums.service.WcnUserService;
import com.woniuxy.uums.mapper.WcnUserMapper;
import com.woniuxy.uums.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;


import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import static com.woniuxy.common.constant.FinanceConstant.User.WONIU;
import static com.woniuxy.common.constant.FinanceConstant.User.WONIUXY;

/**
 * @author yolo
 * @description 针对表【wcn_user(用户表(包含人脸识别信息))】的数据库操作Service实现
 * @createDate 2025-07-16 11:43:42
 */
@Service
@Slf4j
public class WcnUserServiceImpl extends ServiceImpl<WcnUserMapper, WcnUser>
        implements WcnUserService {

    // 定义错误码常量
    private static final int IMAGE_DOWNLOAD_FAILURE_ERROR_CODE_1 = 222202;
    private static final int IMAGE_DOWNLOAD_FAILURE_ERROR_CODE_2 = 222204;
    @Autowired
    private BaiduFaceService baiduFaceService;

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private OwnerService ownerService;

    @Override
    public String login(String username, String password) {
        password = SecureUtil.md5(SecureUtil.md5(password) + WONIU);
        //1\根据用户名和密码查询用户信息2、判断用户是否存在5、存在生成token返回token6、不存在返回null
        WcnUser user = lambdaQuery().eq(WcnUser::getUsername, username).eq(WcnUser::getPassword, password).one();
        if (Objects.isNull(user)) {
            return null;
        }
        Map<String, Object> payload = new HashMap<>(1);//已知长度的集合创建集合时直接指定长度
        //脱敏操作1\把敏感信息删除2、返回没有敏感信息的对象(DTO) 一定在后台脱敏
        user.setPassword(null);
        user.setPhone(null);
        payload.put("user", user);
        return JWTUtil.createToken(payload, WONIUXY.getBytes());
    }

    @Override
    public String loginByVerificationCode(String phone, String code) {
        // 1. 验证验证码
        if (!redisUtil.verifyCode(phone, code)) {
            return null;
        }

        // 2. 根据手机号查询用户
        WcnUser user = getUserByPhone(phone);
        if (Objects.isNull(user)) {
            return null;
        }

        // 3. 检查用户状态
        if (user.getStatus() != null && user.getStatus() == 0) {
            return null; // 用户被禁用
        }

        // 4. 生成JWT token
        Map<String, Object> payload = new HashMap<>(1);
        // 脱敏操作
        user.setPassword(null);
        user.setPhone(null);
        payload.put("user", user);
        return JWTUtil.createToken(payload, WONIUXY.getBytes());
    }

    @Override
    public WcnUser getUserByPhone(String phone) {
        return lambdaQuery().eq(WcnUser::getPhone, phone).one();
    }

    @Override
    public String faceLogin(String faceImage) {
        try {
            // 1. 输入验证
            if (faceImage == null || faceImage.isEmpty()) {
                log.error("人脸图片输入为空");
                return null;
            }

            // 2. 检查是否为Base64格式
            boolean isBase64 = faceImage.startsWith("data:image");
//            if (!isBase64) {
//                log.error("无效的图片格式，仅支持Base64");
//                return null;
//            }

            String result = processBase64Login(faceImage);
            try {
                JSONObject jsonResult = new JSONObject(result.trim()); // 注意trim()处理可能的空格
                return processFaceResult(jsonResult);
            } catch (JSONException e) {
                // 如果解析JSON失败，检查是否是JWT Token（包含两个点的字符串）
                if (result.split("\\.").length == 3) {
                    log.info("人脸识别返回JWT Token，直接使用");
                    return result; // 直接返回Token
                } else {
                    log.error("人脸识别返回无效数据（非JSON也非Token）: {}", result);
                    return null;
                }
            }

        } catch (Exception e) {
            log.error("人脸登录处理异常", e);
            return null;
        }
//        try {
//            // 1. 输入验证
//            if (faceImage == null || faceImage.isEmpty()) {
//                log.error("人脸图片输入为空");
//                return null;
//            }
//
//            JSONObject result = null;
//            boolean isBase64 = faceImage.startsWith("data:image");

        // 2. 优先尝试URL方式
//            if (!isBase64 && faceImage.startsWith("http")) {
//                try {
//                    result = baiduFaceService.searchFace(faceImage, false);
//
//                    // 处理图片下载失败的错误码(222202和222204)
//                    if (result != null &&
//                            (result.getInt("error_code") == IMAGE_DOWNLOAD_FAILURE_ERROR_CODE_1 ||
//                                    result.getInt("error_code") == IMAGE_DOWNLOAD_FAILURE_ERROR_CODE_2)) {
//                        log.warn("URL方式失败({})，尝试Base64方式: {}",
//                                result.getInt("error_code"), faceImage);
//                        return processBase64Login(faceImage);
//                    }
//                } catch (Exception e) {
//                    log.warn("URL方式异常，尝试Base64方式: {}", faceImage, e);
//            processBase64Login(faceImage);
//                }
//            }
//            // 3. Base64方式处理
//            else
//            if (isBase64) {
//                return processBase64Login(faceImage);
//            }
//            // 4. 无效格式
//            else {
//                log.error("无效的图片格式");
//                return null;
//            }
//
//            // 5. 处理识别结果
//            return processFaceResult(result);
//        } catch (Exception e) {
//            log.error("人脸登录处理异常", e);
//            return null;
//        }
    }

    /**
     * 处理Base64格式登录
     */
    private String processBase64Login(String imageInput) throws Exception {
        try {
//            String base64Image = imageInput;
//            byte[] imageData = null;
//
//            // 如果是URL则下载转换
//            if (imageInput.startsWith("http")) {
//                // 1. 下载图片
//                imageData = downloadImageWithRetry(imageInput, 3);
//
//                // 2. 验证图片格式
//                if (!isValidImage(imageData)) {
//                    log.error("下载的图片格式无效");
//                    return null;
//                }
//
//                // 3. 转换为标准JPEG格式的Base64
//                base64Image = convertToStandardJpegBase64(imageData);
//            }
//
//            // 验证Base64格式
//            if (!isValidBase64(base64Image)) {
//                log.error("无效的Base64格式");
//                return null;
//            }


            byte[] imageData = downloadImageWithRetry(imageInput, 3);
            String base64Image = Base64Utils.encodeToString(imageData);

            JSONObject result = baiduFaceService.searchFace(base64Image, true);
            return processFaceResult(result);
        } catch (Exception e) {
            log.error("Base64登录处理异常", e);
            return null;
        }
    }

    /**
     * 验证图片数据有效性
     */
    private boolean isValidImage(byte[] imageData) {
        try {
            BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageData));
            return image != null;
        } catch (IOException e) {
            log.warn("图片格式验证失败", e);
            return false;
        }
    }

    /**
     * 转换为标准JPEG格式的Base64
     */
    private String convertToStandardJpegBase64(byte[] imageData) throws IOException {
        try {
            // 读取原始图片
            BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(imageData));

            // 转换为JPEG格式
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(originalImage, "jpg", baos);

            return "data:image/jpeg;base64," + Base64Utils.encodeToString(baos.toByteArray());
        } catch (IOException e) {
            log.error("图片转换失败", e);
            throw e;
        }
    }

    /**
     * 处理人脸识别结果
     */
    private String processFaceResult(JSONObject result) throws Exception {
        if (result == null || result.getInt("error_code") != 0) {
            log.error("人脸识别失败: {}", result != null ? result.toString() : "null");
            return null;
        }

        JSONObject userList = result.getJSONObject("result")
                .getJSONArray("user_list")
                .getJSONObject(0);

        // 检查匹配度（建议阈值设为80）
        double score = userList.getDouble("score");
        if (score < 50) {
            log.warn("人脸匹配度不足: {}", score);
            return null;
        }

        // 获取用户信息
        String userId = userList.getString("user_id");
        WcnUser user = getById(Long.parseLong(userId));
        if (user == null || user.getStatus() == 0) {
            log.warn("用户不存在或已被禁用: {}", userId);
            return null;
        }

        // 生成JWT令牌
        Map<String, Object> payload = new HashMap<>(1);
        user.setPassword(null);
        user.setPhone(null);
        payload.put("user", user);

        return JWTUtil.createToken(payload, WONIUXY.getBytes());
    }

    /**
     * 带重试机制的图片下载（纯内存操作）
     */
    private byte[] downloadImageWithRetry(String imageUrl, int maxRetries) throws Exception {
        int retryCount = 0;
        Exception lastException = null;

        while (retryCount < maxRetries) {
            try {
                URL url = new URL(imageUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(5000);
                connection.setReadTimeout(10000);

                // 添加必要的请求头
                connection.setRequestProperty("User-Agent", "Mozilla/5.0");
                connection.setRequestProperty("Accept", "image/*");

                // 验证响应状态
                int status = connection.getResponseCode();
                if (status != HttpURLConnection.HTTP_OK) {
                    throw new IOException("HTTP " + status);
                }
                // 验证内容类型
                String contentType = connection.getContentType();
                if (contentType == null || !contentType.startsWith("image/")) {
                    throw new IOException("Invalid content type: " + contentType);
                }

                // 内存中读取数据
                try (InputStream in = connection.getInputStream();
                     ByteArrayOutputStream out = new ByteArrayOutputStream()) {
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = in.read(buffer)) != -1) {
                        out.write(buffer, 0, bytesRead);
                    }
                    return out.toByteArray();
                }
            } catch (Exception e) {
                lastException = e;
                retryCount++;
                if (retryCount < maxRetries) {
                    Thread.sleep(1000 * retryCount); // 指数退避
                }
            }
        }
        throw new Exception("图片下载失败，达到最大重试次数", lastException);
    }

    /**
     * 验证Base64格式
     */
    private boolean isValidBase64(String image) {
        if (!image.startsWith("data:image/")) {
            return false;
        }
        try {
            String base64Data = image.split(",")[1];
            Base64.getDecoder().decode(base64Data);
            return true;
        } catch (Exception e) {
            return false;
        }
    }


}





